package com.mkh.st.common.job.client;

import com.xxl.job.core.biz.model.ReturnT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.time.LocalTime;

/**
 * 任务管理器
 *
 * @Author: pc
 * @CreateDate: 2021/10/21 11:48
 */
@Component
public class JobManager {

	/**
	 * xxl-job rpc接口
	 *
	 */
	private static IJobProdiver jobProdiver;

	/**
	 * 当前服务所对应的执行器id
	 */
	private static Integer currentJobGroup;

	@Autowired
	public JobManager(IJobProdiver jobProdiver) {
		JobManager.jobProdiver = jobProdiver;
	}

	/**
	 * 添加job
	 *
	 */
	public static void initJobGroup(String appName) {
		//查看是否存在执行器
		Integer groupId = jobProdiver.getGroupIdByAppName(appName).getContent();
		if (groupId == null) {
			//若不存在则执行创建执行器动作
			XxlJobGroup xxlJobGroup = new XxlJobGroup();
			xxlJobGroup.setAppname(appName);
			xxlJobGroup.setTitle(appName);
			//自动注册
			xxlJobGroup.setAddressType(0);
			currentJobGroup = jobProdiver.addJobGroup(xxlJobGroup).getContent();
		} else {
			currentJobGroup = groupId;
		}
	}

	/**
	 * 添加job
	 *
	 * @param jobHandler
	 * @param time
	 * @param param
	 * @return
	 */
	public static Integer addTimeJob(String jobHandler, String time, String param) {
		check(jobHandler, time);
		return addJob(jobHandler, getTimeCron(time), param);
	}

	/**
	 * 添加job
	 *
	 * @param jobHandler
	 * @param cron
	 * @param param
	 * @return
	 */
	public static Integer addJob(String jobHandler, String cron, String param) {
		ReturnT<String> result = jobProdiver.addJob(buildJob(jobHandler, cron, param));
		return Integer.valueOf(result.getContent());
	}

	/**
	 * 修改任务
	 *
	 * @param jobId
	 * @param time
	 * @param param
	 * @return
	 */
	public static boolean updateTimeJob(Integer jobId, String time, String param) {
		return updateJob(jobId, getTimeCron(time), param);
	}

	/**
	 * 修改任务
	 *
	 * @param jobId
	 * @param cron
	 * @param param
	 * @return
	 */
	public static boolean updateJob(Integer jobId, String cron, String param) {
		Assert.notNull(jobId, "任务标识不能为空");
		Assert.hasText(cron, "任务周期不能为空");
		//获取任务信息
		XxlJobInfo jobInfo = jobProdiver.getJobInfo(jobId).getContent();
		if (jobInfo == null) {
			return false;
		} else {
			jobInfo.setExecutorParam(param);
			jobInfo.setScheduleConf(cron);
			ReturnT<String> result = jobProdiver.updateJob(jobInfo);
			return result.getCode() == 200;
		}
	}

	/**
	 * 删除任务
	 *
	 * @param jobId
	 * @return
	 */
	public static boolean removeJob(Integer jobId) {
		ReturnT<String> result = jobProdiver.remove(jobId);
		return result.getCode() == 200;
	}

	/**
	 * 开始任务
	 *
	 * @param jobId
	 * @return
	 */
	public static boolean startJob(Integer jobId) {
		ReturnT<String> result = jobProdiver.start(jobId);
		return result.getCode() == 200;
	}

	/**
	 * 停止任务
	 *
	 * @param jobId
	 * @return
	 */
	public static boolean stopJob(Integer jobId) {
		ReturnT<String> result = jobProdiver.pause(jobId);
		return result.getCode() == 200;
	}

	/**
	 * 构建任务
	 *
	 * @param jobHandler
	 * @param cron
	 * @param param
	 * @return
	 */
	private static XxlJobInfo buildJob(String jobHandler, String cron, String param) {
		XxlJobInfo xxlJobInfo = new XxlJobInfo();
		xxlJobInfo.setJobGroup(currentJobGroup);
		xxlJobInfo.setScheduleType("CRON");
		xxlJobInfo.setScheduleConf(cron);
		xxlJobInfo.setGlueType("BEAN");
		xxlJobInfo.setMisfireStrategy("DO_NOTHING");
		xxlJobInfo.setExecutorRouteStrategy("FIRST");
		xxlJobInfo.setExecutorHandler(jobHandler);
		xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
		xxlJobInfo.setGlueRemark("GLUE代码初始化");
		xxlJobInfo.setExecutorParam(param);
		xxlJobInfo.setJobDesc("系统自建");
		xxlJobInfo.setAuthor("admin");
		return xxlJobInfo;
	}

	/**
	 * 获取时间cron表达式
	 *
	 * @param time
	 * @return
	 */
	private static String getTimeCron(String time) {
		LocalTime parse = LocalTime.parse(time);
		TaskScheduleBuilder instance = TaskScheduleBuilder.getInstance();
		instance.setHour(String.valueOf(parse.getHour()));
		instance.setMinute(String.valueOf(parse.getMinute()));
		instance.setSecond(String.valueOf(parse.getSecond()));
		return instance.getSchedule();
	}

	/**
	 * 检查参数
	 *
	 * @param jobHandler
	 * @param time
	 */
	private static void check(String jobHandler, String time) {
		Assert.hasText(jobHandler, "jobHandler不能为空");
		Assert.hasText(time, "任务调度周期不能为空");
	}

}
